package com.xbongbong.paas.service.impl;

import com.alibaba.dingtalk.openapi.helper.AuthHelper;
import com.alibaba.dingtalk.openapi.helper.DingtalkWorkrecordHelper;
import com.alibaba.dingtalk.openapi.helper.Env;
import com.alibaba.dingtalk.openapi.vo.workrecord.FormComponentPropVo;
import com.alibaba.dingtalk.openapi.vo.workrecord.FormComponentVo;
import com.alibaba.dingtalk.openapi.vo.workrecord.SaveProcess;
import com.alibaba.dingtalk.openapi.vo.workrecord.SaveProcessRequest;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.constant.TimeConstant;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.elasticsearch.pojo.XbbAggregatedPage;
import com.xbongbong.paas.elasticsearch.util.EsUtil;
import com.xbongbong.paas.elasticsearch.util.XbbElasticsearchRestTemplate;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.DingtalkFieldTypeEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.help.CommonHelp;
import com.xbongbong.paas.help.menu.InitJxcMenuHelp;
import com.xbongbong.paas.log.MongoLogHelp;
import com.xbongbong.paas.log.constant.LogMemoConstant;
import com.xbongbong.paas.log.pojo.InfoArrPojo;
import com.xbongbong.paas.model.PaasFormExplainModel;
import com.xbongbong.paas.pojo.AccordConfigMenuPojo;
import com.xbongbong.paas.pojo.ReportTargetPoJo;
import com.xbongbong.paas.pojo.dto.ReportTargetEnableDTO;
import com.xbongbong.paas.pojo.vo.ReportTargetVO;
import com.xbongbong.paas.redis.PaasRedisHelper;
import com.xbongbong.paas.redis.RedisConstant;
import com.xbongbong.paas.redis.RedisPrefixConstant;
import com.xbongbong.paas.redis.RedisTimeConstant;
import com.xbongbong.paas.service.CompanyConfigService;
import com.xbongbong.paas.service.FormConfigService;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.paas.toolbox.util.JsonHelperUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.toolbox.wrap.BaseDTO;
import com.xbongbong.paas.toolbox.wrap.BaseVO;
import com.xbongbong.pro.companyconfig.pojo.CompanyConfigEnableAndMemoPojo;
import com.xbongbong.pro.companyconfig.pojo.CompanyConfigEnablePojo;
import com.xbongbong.pro.companyconfig.pojo.CompanyConfigWorkrecordValuePojo;
import com.xbongbong.pro.companyconfig.pojo.dto.CompanyConfigAddBatchDTO;
import com.xbongbong.pro.companyconfig.pojo.dto.CompanyConfigAddDTO;
import com.xbongbong.pro.companyconfig.pojo.dto.CompanyConfigEnableDTO;
import com.xbongbong.pro.companyconfig.pojo.dto.CompanyConfigFindDTO;
import com.xbongbong.pro.companyconfig.pojo.dto.CompanyConfigGetFiscalDTO;
import com.xbongbong.pro.companyconfig.pojo.dto.CompanyConfigGetJxcConfigDTO;
import com.xbongbong.pro.companyconfig.pojo.dto.CompanyConfigGetPerformanceFinishDTO;
import com.xbongbong.pro.companyconfig.pojo.dto.CompanyConfigGetPerformanceLeaveDTO;
import com.xbongbong.pro.companyconfig.pojo.dto.CompanyConfigGetWorkingDayMonthDTO;
import com.xbongbong.pro.companyconfig.pojo.dto.CompanyConfigGetWorkingDayWeekDTO;
import com.xbongbong.pro.companyconfig.pojo.dto.CompanyConfigHasBeenEnableBatchDTO;
import com.xbongbong.pro.companyconfig.pojo.dto.CompanyConfigHasBeenEnableDTO;
import com.xbongbong.pro.companyconfig.pojo.dto.CompanyConfigHasBeenSetDTO;
import com.xbongbong.pro.companyconfig.pojo.dto.CompanyConfigRaidersWhiteDTO;
import com.xbongbong.pro.companyconfig.pojo.dto.CompanyConfigSaveBatchDTO;
import com.xbongbong.pro.companyconfig.pojo.dto.CompanyConfigSetFiscalDTO;
import com.xbongbong.pro.companyconfig.pojo.dto.CompanyConfigSetPerformanceFinishDTO;
import com.xbongbong.pro.companyconfig.pojo.dto.CompanyConfigSetWorkingDayMonthDTO;
import com.xbongbong.pro.companyconfig.pojo.dto.CompanyConfigSetWorkingDayWeekDTO;
import com.xbongbong.pro.companyconfig.pojo.dto.CompanyConfigSetWorkrecordDTO;
import com.xbongbong.pro.companyconfig.pojo.vo.CompanyConfigAddBatchVO;
import com.xbongbong.pro.companyconfig.pojo.vo.CompanyConfigEnableVO;
import com.xbongbong.pro.companyconfig.pojo.vo.CompanyConfigFindVO;
import com.xbongbong.pro.companyconfig.pojo.vo.CompanyConfigGetFiscalVO;
import com.xbongbong.pro.companyconfig.pojo.vo.CompanyConfigGetPerformanceFinishVO;
import com.xbongbong.pro.companyconfig.pojo.vo.CompanyConfigGetPerformanceLeaveVO;
import com.xbongbong.pro.companyconfig.pojo.vo.CompanyConfigGetWorkingDayMonthVO;
import com.xbongbong.pro.companyconfig.pojo.vo.CompanyConfigGetWorkingDayWeekVO;
import com.xbongbong.pro.companyconfig.pojo.vo.CompanyConfigHasBeenEnableBatchVO;
import com.xbongbong.pro.companyconfig.pojo.vo.CompanyConfigHasBeenEnableVO;
import com.xbongbong.pro.companyconfig.pojo.vo.CompanyConfigHasBeenSetVO;
import com.xbongbong.pro.companyconfig.pojo.vo.CompanyConfigJxcConfigVO;
import com.xbongbong.pro.companyconfig.pojo.vo.CompanyConfigRaidersWhiteVO;
import com.xbongbong.pro.companyconfig.pojo.vo.CompanyConfigSetFiscalVO;
import com.xbongbong.pro.companyconfig.pojo.vo.CompanyConfigSetPerformanceFinishVO;
import com.xbongbong.pro.companyconfig.pojo.vo.CompanyConfigSetWorkingDayMonthVO;
import com.xbongbong.pro.companyconfig.pojo.vo.CompanyConfigSetWorkingDayWeekVO;
import com.xbongbong.pro.companyconfig.pojo.vo.CompanyConfigSetWorkrecordVO;
import com.xbongbong.pro.companyconfig.pojo.vo.CompanyConfigValueSetWorkrecordVO;
import com.xbongbong.pro.companyconfig.pojo.vo.JXCSetListVO;
import com.xbongbong.pro.config.ProBaseConfig;
import com.xbongbong.pro.constant.BusinessConstant;
import com.xbongbong.pro.constant.ElasticConstant;
import com.xbongbong.pro.constant.I18nStringConstant;
import com.xbongbong.pro.constant.RaidersConstant;
import com.xbongbong.pro.enums.errorcodes.PerformanceErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.ProductErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.RaidersErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SaleReportErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.menu.enums.JxcSetEnum;
import com.xbongbong.pro.enums.workrecord.enums.WorkrecordTemplateEnum;
import com.xbongbong.pro.flowbill.dto.FlowBillInsertDTO;
import com.xbongbong.pro.form.pojo.FormConfigEnablePoJo;
import com.xbongbong.pro.form.pojo.FormConfigPoJo;
import com.xbongbong.pro.form.pojo.dto.CustomerCheckRepeatRuleGetDTO;
import com.xbongbong.pro.form.pojo.vo.CustomerCheckRepeatRuleGetVO;
import com.xbongbong.pro.form.pojo.vo.CustomerCheckSetConfigGetVO;
import com.xbongbong.pro.form.pojo.vo.FormConfigGetVO;
import com.xbongbong.pro.fundset.pojo.FundSetMenuPojo;
import com.xbongbong.pro.log.pojo.DetailLogPojo;
import com.xbongbong.pro.script.pojo.dto.BlacklistBigDataCorpDTO;
import com.xbongbong.pro.script.pojo.vo.ScriptVO;
import com.xbongbong.pro.service.toolbox.statistic.help.FiscalYearHelp;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.ParameterConstant;
import com.xbongbong.saas.constant.ProductConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.enums.BusinessTypeToServiceEnum;
import com.xbongbong.saas.enums.CompanyConfigEnum;
import com.xbongbong.saas.enums.FormConfigEnum;
import com.xbongbong.saas.enums.OperateModuleTypeEnum;
import com.xbongbong.saas.enums.OperateTypeEnum;
import com.xbongbong.saas.enums.ReportTargetEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.ProductEnum;
import com.xbongbong.saas.factory.business.AutoRegisterHandleSpecialBusinessFactory;
import com.xbongbong.saas.model.BatchFlowBillModel;
import com.xbongbong.saas.model.BatchSurplusRecordModel;
import com.xbongbong.saas.model.StockFlowBillModel;
import com.xbongbong.saas.model.StockSurplusRecordModel;
import com.xbongbong.saas.service.BatchFlowBillService;
import com.xbongbong.saas.service.ProductService;
import com.xbongbong.saas.service.StockFlowBillService;
import com.xbongbong.saas.service.toolbox.help.AttrDecimalPrecisionHelper;
import com.xbongbong.saas.service.toolbox.help.LogHelp;
import com.xbongbong.sys.domain.entity.CompanyConfigEntity;
import com.xbongbong.sys.model.CompanyConfigModel;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;

/**
 * @description: 公司配置
 * @Author: hongxiao
 * @date: 2019-01-21 16:14
 */
@Service("companyConfigService")
public class CompanyConfigServiceImpl implements CompanyConfigService {

    private static final Logger LOG = LoggerFactory.getLogger(CompanyConfigServiceImpl.class);

    private static final String SEPARATOR = "|";

    @Resource
    private CompanyConfigModel companyConfigModel;
    @Resource
    private PaasRedisHelper paasRedisHelper;
    @Resource
    private MongoLogHelp mongoLogHelp;
    @Resource
    private FormConfigService formConfigService;
    @Resource
    private AuthHelper authHelper;
    @Resource
    private ProBaseConfig proBaseConfig;
    @Resource
    private InitJxcMenuHelp initJxcMenuHelp;
    @Resource
    private StockFlowBillModel stockFlowBillModel;
    @Resource
    private StockSurplusRecordModel stockSurplusRecordModel;
    @Resource
    private StockFlowBillService stockFlowBillService;
    @Resource
    private ProductService productService;
    @Resource
    private PaasFormExplainModel paasFormExplainModel;
    @Resource
    private BatchFlowBillModel batchFlowBillModel;
    @Resource
    private BatchSurplusRecordModel batchSurplusRecordModel;
    @Resource
    private BatchFlowBillService batchFlowBillService;
    @Resource
    private XbbElasticsearchRestTemplate xbbElasticsearchRestTemplate;
    @Resource
    private AutoRegisterHandleSpecialBusinessFactory autoRegisterHandleSpecialBusinessFactory;
    @Resource
    private CommonHelp commonHelp;
    @Resource
    private LogHelp logHelp;
    @Resource
    private PaasCompanyConfigServiceImpl paasCompanyConfigService;

    @Override
    public CompanyConfigEnableVO enable(CompanyConfigEnableDTO companyConfigEnableDTO) throws XbbException {
        return paasCompanyConfigService.enable(companyConfigEnableDTO);
    }

    @Override
    public CompanyConfigGetFiscalVO getFiscal(CompanyConfigGetFiscalDTO companyConfigGetFiscalDTO) throws XbbException {
        CompanyConfigGetFiscalVO getFiscalVO = new CompanyConfigGetFiscalVO();

        String corpid = companyConfigGetFiscalDTO.getCorpid();
        String key = corpid + StringConstant.COLON + CompanyConfigEnum.FISCAL_YEAR.getAlias();
        String redisStr = paasRedisHelper.getValue(RedisConstant.KEY_COMPANY_CONFIG, key);
        Integer startMonth = null;
        if (redisStr != null) {
            try {
                startMonth = Integer.valueOf(redisStr);
            } catch (NumberFormatException e) {
                // 设置默认值
                startMonth = 1;
            }
        }

        if (startMonth == null) {
            try {
                startMonth = companyConfigModel.getFiscalStartMonth(corpid);
            } catch (Exception e) {
                LOG.error("获取公司财年配置失败", e);
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
            }
        }

        getFiscalVO.setStartMonth(startMonth);
        getFiscalVO.setFiscalYear(DateUtil.getFiscalYear4Now(startMonth));
        getFiscalVO.setLabelFiscalYear(FiscalYearHelp.getLableFiscalYear(startMonth, null));

        return getFiscalVO;
    }

    @Override
    public CompanyConfigSetFiscalVO setFiscal(CompanyConfigSetFiscalDTO companyConfigSetFiscalDTO) throws XbbException {
        CompanyConfigSetFiscalVO setFiscalVO = new CompanyConfigSetFiscalVO();

        String corpid = companyConfigSetFiscalDTO.getCorpid();
        String userId = companyConfigSetFiscalDTO.getUserId();
        // 登录用户名
        String loginUserName = companyConfigSetFiscalDTO.getLoginUserName();
        Integer startMonth = companyConfigSetFiscalDTO.getStartMonth();
        CompanyConfigEnum fiscalYearEnum = CompanyConfigEnum.FISCAL_YEAR;

        //获取旧的起始月
        int oldStartMonth = companyConfigModel.getFiscalStartMonth(corpid);

        //变更
        CompanyConfigEntity configEntity;
        try {
            configEntity = companyConfigModel.setFiscalStartMonth(corpid, startMonth);
        } catch (Exception e) {
            LOG.error("获取公司财年配置失败", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }

        // 缓存
        String key = corpid + StringConstant.COLON + fiscalYearEnum.getAlias();
        paasRedisHelper.setValue(RedisConstant.KEY_COMPANY_CONFIG, key, startMonth,
                TimeConstant.SECONDS_EIGHT_HOUR);

        // 日志
        List<DetailLogPojo> detailArr = logHelp.detailLog4WorkDay(corpid,String.valueOf(oldStartMonth),String.valueOf(startMonth),fiscalYearEnum);
        String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_UPDATE_COMPANY_FISCAL_YEAR_START_MONTH), loginUserName, startMonth);
        mongoLogHelp.buildLog4DetailArr(detailArr,corpid, userId, loginUserName, OperateModuleTypeEnum.COMPANY_CONFIG, OperateTypeEnum.EDIT, configEntity.getId().toString(), OperateModuleTypeEnum.COMPANY_CONFIG.getName(), memo, companyConfigSetFiscalDTO.getHttpHeader());
        return setFiscalVO;
    }

    @Override
    public CompanyConfigGetWorkingDayMonthVO getWorkingDayMonth(CompanyConfigGetWorkingDayMonthDTO companyConfigGetWorkingDayMonthDTO) throws XbbException {
        CompanyConfigGetWorkingDayMonthVO getWorkingDayMonthVO = new CompanyConfigGetWorkingDayMonthVO();

        String corpid = companyConfigGetWorkingDayMonthDTO.getCorpid();
        String key = corpid + StringConstant.COLON + CompanyConfigEnum.WORKING_DAY_MONTH.getAlias();
        String redisStr = paasRedisHelper.getValue(RedisConstant.KEY_COMPANY_CONFIG, key);
        Double workDays = null;
        if (redisStr != null) {
            try {
                workDays = Double.parseDouble(redisStr);
            } catch (NumberFormatException e) {
                // 设置默认值
                workDays = Double.parseDouble(CompanyConfigEnum.WORKING_DAY_MONTH.getValue());
            }
        }

        if (workDays == null) {
            workDays = companyConfigModel.getWorkingDayMonth(corpid);
        }
        getWorkingDayMonthVO.setWorkingDayMonth(workDays);
        return getWorkingDayMonthVO;
    }

    @Override
    public CompanyConfigSetWorkingDayMonthVO setWorkingDayMonth(CompanyConfigSetWorkingDayMonthDTO companyConfigSetWorkingDayMonthDTO) throws XbbException {
        CompanyConfigSetWorkingDayMonthVO setWorkingDayMonthVO = new CompanyConfigSetWorkingDayMonthVO();
        String userId = companyConfigSetWorkingDayMonthDTO.getUserId();
        // 登录用户名
        String loginUserName = companyConfigSetWorkingDayMonthDTO.getLoginUserName();
        String corpid = companyConfigSetWorkingDayMonthDTO.getCorpid();
        String workingDayMonth = String.valueOf(companyConfigSetWorkingDayMonthDTO.getWorkingDayMonth());

        CompanyConfigEnum workingDayMonthEnum = CompanyConfigEnum.WORKING_DAY_MONTH;
        CompanyConfigEntity configEntity;
        String oldValue;
        try {
            configEntity = companyConfigModel.initConfigEntity(corpid, workingDayMonthEnum.getAlias());
            oldValue = configEntity.getConfigValue();
            configEntity.setConfigValue(workingDayMonth);
            companyConfigModel.update(configEntity);
        } catch (Exception e) {
            LOG.error("获取每月工作天数失败", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }

        // 缓存
        String key = corpid + StringConstant.COLON + workingDayMonthEnum.getAlias();
        paasRedisHelper.setValue(RedisConstant.KEY_COMPANY_CONFIG, key, workingDayMonth,
                TimeConstant.SECONDS_EIGHT_HOUR);

        // 日志
        List<DetailLogPojo> detailArr = logHelp.detailLog4WorkDay(corpid,oldValue,workingDayMonth,workingDayMonthEnum);
        String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_SET_WORK_DAY_MONTH), loginUserName, workingDayMonth);
        mongoLogHelp.buildLog4DetailArr(detailArr,corpid, userId, loginUserName, OperateModuleTypeEnum.COMPANY_CONFIG, OperateTypeEnum.SET, configEntity.getId().toString(), OperateModuleTypeEnum.COMPANY_CONFIG.getName(), memo, companyConfigSetWorkingDayMonthDTO.getHttpHeader());

        return setWorkingDayMonthVO;
    }

    @Override
    public CompanyConfigGetWorkingDayWeekVO getWorkingDayWeek(CompanyConfigGetWorkingDayWeekDTO companyConfigGetWorkingDayWeekDTO) throws XbbException {
        CompanyConfigGetWorkingDayWeekVO getWorkingDayWeekVO = new CompanyConfigGetWorkingDayWeekVO();

        String corpid = companyConfigGetWorkingDayWeekDTO.getCorpid();
        Double workDays = null;
        String key = corpid + StringConstant.COLON + CompanyConfigEnum.WORKING_DAY_WEEK.getAlias();
        String redisStr = paasRedisHelper.getValue(RedisConstant.KEY_COMPANY_CONFIG, key);
        if (redisStr != null) {
            try {
                workDays = Double.parseDouble(redisStr);
            } catch (NumberFormatException e) {
                workDays = Double.parseDouble(CompanyConfigEnum.WORKING_DAY_WEEK.getValue());
            }
        }

        if (workDays == null) {
            try {
                workDays = companyConfigModel.getWorkingDayWeek(corpid);
            } catch (Exception e) {
                LOG.error("获取每周工作天数失败", e);
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
            }
        }

        getWorkingDayWeekVO.setWorkingDayWeek(workDays);
        return getWorkingDayWeekVO;
    }

    @Override
    public CompanyConfigSetWorkingDayWeekVO setWorkingDayWeek(CompanyConfigSetWorkingDayWeekDTO companyConfigSetWorkingDayWeekDTO) throws XbbException {
        CompanyConfigSetWorkingDayWeekVO setWorkingDayWeekVO = new CompanyConfigSetWorkingDayWeekVO();
        String userId = companyConfigSetWorkingDayWeekDTO.getUserId();
        // 登录用户名
        String loginUserName = companyConfigSetWorkingDayWeekDTO.getLoginUserName();
        String corpid = companyConfigSetWorkingDayWeekDTO.getCorpid();
        String workingDayWeek = String.valueOf(companyConfigSetWorkingDayWeekDTO.getWorkingDayWeek());

        CompanyConfigEnum workingDayWeekEnum = CompanyConfigEnum.WORKING_DAY_WEEK;
        CompanyConfigEntity configEntity;
        String oldValue;
        try {
            configEntity = companyConfigModel.initConfigEntity(corpid, workingDayWeekEnum.getAlias());
            oldValue = configEntity.getConfigValue();
            configEntity.setConfigValue(workingDayWeek);
            companyConfigModel.update(configEntity);
        } catch (Exception e) {
            LOG.error("获取每周工作天数失败", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }

        // 缓存
        String key = corpid + StringConstant.COLON + workingDayWeekEnum.getAlias();
        paasRedisHelper.setValue(RedisConstant.KEY_COMPANY_CONFIG, key, workingDayWeek,
                TimeConstant.SECONDS_EIGHT_HOUR);

        // 日志
        List<DetailLogPojo> detailArr = logHelp.detailLog4WorkDay(corpid,oldValue,workingDayWeek,workingDayWeekEnum);
        String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_SET_WORK_DAY_WEEK), loginUserName, workingDayWeek);
        mongoLogHelp.buildLog4DetailArr(detailArr,corpid, userId, loginUserName, OperateModuleTypeEnum.COMPANY_CONFIG, OperateTypeEnum.SET, configEntity.getId().toString(), OperateModuleTypeEnum.COMPANY_CONFIG.getName(), memo, companyConfigSetWorkingDayWeekDTO.getHttpHeader());

        return setWorkingDayWeekVO;
    }

    @Override
    public CompanyConfigGetPerformanceFinishVO getPerformanceFinish(CompanyConfigGetPerformanceFinishDTO companyConfigGetPerformanceFinishDTO) throws XbbException {
        CompanyConfigGetPerformanceFinishVO getPerformanceFinishVO = new CompanyConfigGetPerformanceFinishVO();

        String corpid = companyConfigGetPerformanceFinishDTO.getCorpid();

        String downKey = corpid + StringConstant.COLON + CompanyConfigEnum.PERFORMANCE_FINISH_DOWN.getAlias();
        String upKey = corpid + StringConstant.COLON + CompanyConfigEnum.PERFORMANCE_FINISH_UP.getAlias();
        String downRedisStr = paasRedisHelper.getValue(RedisConstant.KEY_COMPANY_CONFIG, downKey);
        String upRedisStr = paasRedisHelper.getValue(RedisConstant.KEY_COMPANY_CONFIG, upKey);
        Integer performanceFinishDown = null;
        Integer performanceFinishUp = null;
        if (downRedisStr != null) {
            try {
                performanceFinishDown = Integer.parseInt(downRedisStr);
            } catch (NumberFormatException e) {
                performanceFinishDown = Integer.parseInt(CompanyConfigEnum.PERFORMANCE_FINISH_DOWN.getValue());
            }
        }
        if (upRedisStr != null) {
            try {
                performanceFinishUp = Integer.parseInt(upRedisStr);
            } catch (NumberFormatException e) {
                performanceFinishUp = Integer.parseInt(CompanyConfigEnum.PERFORMANCE_FINISH_UP.getValue());
            }
        }

        if (performanceFinishDown == null) {
            try {
                CompanyConfigEntity configEntity = companyConfigModel.initConfigEntity(corpid, CompanyConfigEnum.PERFORMANCE_FINISH_DOWN.getAlias());
                performanceFinishDown = Integer.parseInt(configEntity.getConfigValue());
            } catch (NumberFormatException e) {
                performanceFinishDown = Integer.parseInt(CompanyConfigEnum.PERFORMANCE_FINISH_DOWN.getValue());
            } catch (Exception e) {
                LOG.error("获取Web端完成情况中完成率颜色区间失败", e);
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
            }
        }
        if (performanceFinishUp == null) {
            try {
                CompanyConfigEntity configEntity = companyConfigModel.initConfigEntity(corpid, CompanyConfigEnum.PERFORMANCE_FINISH_UP.getAlias());
                performanceFinishUp = Integer.parseInt(configEntity.getConfigValue());
            } catch (NumberFormatException e) {
                performanceFinishUp = Integer.parseInt(CompanyConfigEnum.PERFORMANCE_FINISH_UP.getValue());
            } catch (Exception e) {
                LOG.error("获取Web端完成情况中完成率颜色区间失败", e);
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
            }
        }

        getPerformanceFinishVO.setPerformanceFinishDown(performanceFinishDown);
        getPerformanceFinishVO.setPerformanceFinishUp(performanceFinishUp);

        return getPerformanceFinishVO;
    }

    @Override
    public CompanyConfigSetPerformanceFinishVO setPerformanceFinish(CompanyConfigSetPerformanceFinishDTO companyConfigSetPerformanceFinishDTO) throws XbbException {
        CompanyConfigSetPerformanceFinishVO setPerformanceFinishVO = new CompanyConfigSetPerformanceFinishVO();
        String userId = companyConfigSetPerformanceFinishDTO.getUserId();
        // 登录用户名
        String loginUserName = companyConfigSetPerformanceFinishDTO.getLoginUserName();
        String corpid = companyConfigSetPerformanceFinishDTO.getCorpid();
        Integer performanceFinishDown = companyConfigSetPerformanceFinishDTO.getPerformanceFinishDown();
        Integer performanceFinishUp = companyConfigSetPerformanceFinishDTO.getPerformanceFinishUp();

        if (performanceFinishDown >= performanceFinishUp) {
            throw new XbbException(PerformanceErrorCodeEnum.API_ERROR_240015, PerformanceErrorCodeEnum.API_ERROR_240015.getMsg(), I18nMessageUtil.getMessage(I18nStringConstant.COMPLETE_RATE_LOWER_INTERVAL), I18nMessageUtil.getMessage(I18nStringConstant.COMPLETE_RATE_LOWER_INTERVAL));
        }

        CompanyConfigEnum performanceFinishDownEnum = CompanyConfigEnum.PERFORMANCE_FINISH_DOWN;
        CompanyConfigEnum performanceFinishUpEnum = CompanyConfigEnum.PERFORMANCE_FINISH_UP;
        CompanyConfigEntity performanceFinishUpEntity;
        try {
            CompanyConfigEntity performanceFinishDownEntity = companyConfigModel.initConfigEntity(corpid, performanceFinishDownEnum.getAlias());
            performanceFinishDownEntity.setConfigValue(String.valueOf(performanceFinishDown));
            companyConfigModel.update(performanceFinishDownEntity);

            performanceFinishUpEntity = companyConfigModel.initConfigEntity(corpid, performanceFinishUpEnum.getAlias());
            performanceFinishUpEntity.setConfigValue(String.valueOf(performanceFinishUp));
            companyConfigModel.update(performanceFinishUpEntity);
        } catch (Exception e) {
            LOG.error("设置Web端完成情况中完成率颜色区间失败", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }

        // 缓存
        String downKey = corpid + StringConstant.COLON + CompanyConfigEnum.PERFORMANCE_FINISH_DOWN.getAlias();
        String upKey = corpid + StringConstant.COLON + CompanyConfigEnum.PERFORMANCE_FINISH_UP.getAlias();
        paasRedisHelper.setValue(RedisConstant.KEY_COMPANY_CONFIG, downKey, performanceFinishDown,
                TimeConstant.SECONDS_EIGHT_HOUR);
        paasRedisHelper.setValue(RedisConstant.KEY_COMPANY_CONFIG, upKey, performanceFinishUp,
                TimeConstant.SECONDS_EIGHT_HOUR);

        // 日志
        String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_SET_PERFORMANCE_FINSH), loginUserName);
        mongoLogHelp.buildLog(corpid, userId, loginUserName, OperateModuleTypeEnum.PerformanceObject, OperateTypeEnum.SET, performanceFinishUpEntity.getId().toString(), OperateModuleTypeEnum.COMPANY_CONFIG.getName(), memo, companyConfigSetPerformanceFinishDTO.getHttpHeader());

        return setPerformanceFinishVO;
    }

    @Override
    public CompanyConfigHasBeenSetVO hasBeenSet(CompanyConfigHasBeenSetDTO hasBeenSetDTO) throws XbbException {

        CompanyConfigHasBeenSetVO hasBeenSetVO = new CompanyConfigHasBeenSetVO();
        String corpid = hasBeenSetDTO.getCorpid();
        String alias = hasBeenSetDTO.getAlias();

        hasBeenSetVO.setEnable(false);
        try {
            CompanyConfigEntity configEntity = companyConfigModel.getByConfigAlias(alias, corpid);
            if (configEntity != null) {
                hasBeenSetVO.setEnable(true);
            }
        } catch (Exception e) {
            LOG.error("获取公司配置失败", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }

        return hasBeenSetVO;
    }

    @Override
    public CompanyConfigHasBeenEnableVO hasBeenEnable(CompanyConfigHasBeenEnableDTO hasBeenEnableDTO) throws XbbException {
        CompanyConfigHasBeenEnableVO hasBeenEnableVO = new CompanyConfigHasBeenEnableVO();

        String corpid = hasBeenEnableDTO.getCorpid();
        String alias = hasBeenEnableDTO.getAlias();

        hasBeenEnableVO.setAlias(alias);
        Integer enable = companyConfigModel.hasBeenEnable(corpid, alias);
        hasBeenEnableVO.setEnable(enable);

        return hasBeenEnableVO;
    }

    @Override
    public CompanyConfigHasBeenEnableBatchVO hasBeenEnableBatch(CompanyConfigHasBeenEnableBatchDTO hasBeenEnableBatchDTO) throws XbbException {
        CompanyConfigHasBeenEnableBatchVO hasBeenEnableBatchVO = new CompanyConfigHasBeenEnableBatchVO();

        String corpid = hasBeenEnableBatchDTO.getCorpid();
        List<String> aliasList = hasBeenEnableBatchDTO.getAliasList();
        if (aliasList == null || aliasList.size() == 0) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100089);
        }
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("corpid", corpid);
        param.put("del", DelEnum.NORMAL.getDel());
        param.put("configAliasIn", aliasList);
        param.put("start", 0);
        param.put("pageNum", aliasList.size());

        List<CompanyConfigEntity> list = companyConfigModel.findEntitys(param);

        List<CompanyConfigEnablePojo> enableList = new ArrayList<>();
        List<String> hasBeenAliasList = new ArrayList<>();
        // 已入库的公司配置
        for (CompanyConfigEntity configEntity : list) {
            String alias = configEntity.getConfigAlias();
            int enable;
            try {
                enable = Integer.parseInt(configEntity.getConfigValue());
            } catch (NumberFormatException e) {
                enable = BasicConstant.NO_USE;
            }
            CompanyConfigEnablePojo pojo = new CompanyConfigEnablePojo(alias, enable, configEntity.getConfigName());
            enableList.add(pojo);

            hasBeenAliasList.add(alias);
        }

        // 未入库配置
        List<String> noHasBeenAliasList = new ArrayList<>(aliasList);
        noHasBeenAliasList.removeAll(hasBeenAliasList);
        for (String alias : noHasBeenAliasList) {
            // 未入库配置取枚举里的默认配置值
            CompanyConfigEnum configEnum = CompanyConfigEnum.getByAlias(alias);
            CompanyConfigEnablePojo pojo;
            if (configEnum == null) {
                pojo = new CompanyConfigEnablePojo(alias, BasicConstant.NO_USE);
            } else {
                int enable;
                try {
                    enable = Integer.parseInt(configEnum.getValue());
                } catch (NumberFormatException e) {
                    enable = BasicConstant.NO_USE;
                }
                pojo = new CompanyConfigEnablePojo(alias, enable, configEnum.getName());
            }
            enableList.add(pojo);
        }

        hasBeenEnableBatchVO.setList(enableList);

        return hasBeenEnableBatchVO;
    }

    /**
     * 获取 跟进记录 是否在拨号后自动添加跟进记录
     *
     * @param corpid 公司id
     * @return
     * @throws XbbException
     */
    @Override
    public boolean isVisitAutoAfterCallCheck(String corpid) throws XbbException {
        String configAlias = CompanyConfigEnum.VISIT_IS_AUTO_AFTER_CALL_CHECK.getAlias();
        String isEnable = paasRedisHelper.getValue(RedisConstant.KEY_COMPANY_CONFIG,
                corpid + StringConstant.COLON + configAlias);
        if (StringUtil.isNotEmpty(isEnable) && isEnable.equals(RedisConstant.VALUE_ENABLE)) {
            return true;
        } else {

            CompanyConfigEntity companyConfig = companyConfigModel.getByConfigAlias(configAlias, corpid);

            String configValue = null;
            if (companyConfig != null) {
                configValue = companyConfig.getConfigValue();
            }

            if (StringUtil.isNotEmpty(configValue) && StringConstant.POSITIVE_NUMBER.equals(configValue)) {
                paasRedisHelper.setValue(RedisConstant.KEY_COMPANY_CONFIG, corpid + StringConstant.COLON + configAlias,
                        RedisConstant.VALUE_ENABLE, RedisConstant.COMMON_DURATION);
                return true;
            } else {
                return false;
            }
        }
    }

    /**
     * 通过CompanyConfig表的configValue值来获取启用的指标枚举：按照模块归类
     *
     * @param baseDTO
     * @return
     * @throws XbbException
     */
    @Override
    public ReportTargetVO getReportTarget(BaseDTO baseDTO) throws XbbException {
        ReportTargetVO reportTargetVO = new ReportTargetVO();
        CompanyConfigEntity reportTarget = initConfigEntity(baseDTO.getCorpid(), CompanyConfigEnum.REPORT_TARGETSET.getAlias(), CompanyConfigEnum.REPORT_TARGETSET.getName(), ReportTargetEnum.getAllIndex2ConfigValue());
        //简报指标code --用|隔开  |1|2|3|4|5|6|7|8|9|
        String configValue = reportTarget.getConfigValue();
        //设置简报指标
        Map<Integer, List<JSONObject>> belongObjMap = new LinkedHashMap<>();
        for (ReportTargetEnum cache : ReportTargetEnum.values()) {
            JSONObject object = new JSONObject();
            Integer code = cache.getCode();
            String name = cache.getName();
            Integer belong = cache.getBelong();
            Integer crmOrJxc = cache.getCrmOrJxc();
            //简报指标code
            object.put("code", code);
            //简报指标名称
            object.put("name", name);
            //0未启用 1启用
            int enable = 0;
            if (StringUtil.isNotEmpty(configValue) && configValue.contains(SEPARATOR + code + SEPARATOR)) {
                enable = 1;
            }
            object.put("enable", enable);

            List<JSONObject> targetList = belongObjMap.get(belong);
            if (targetList == null) {
                targetList = new ArrayList<>();
            }
            targetList.add(object);
            belongObjMap.put(belong, targetList);
        }
        List<ReportTargetPoJo> allTargetList = new ArrayList<>();
        for (Map.Entry<Integer, List<JSONObject>> entry : belongObjMap.entrySet()) {
            String belongName = ReportTargetEnum.getBelongName(entry.getKey());
            ReportTargetPoJo object = new ReportTargetPoJo();
            //模块名
            object.setName(belongName);
            //模块内的指标list
            object.setTargetList(entry.getValue());
            allTargetList.add(object);
        }
        reportTargetVO.setList(allTargetList);
        return reportTargetVO;
    }

    /**
     * 获取配置，数据库没有(说明公司还未设置)，则初始化(插入一条默认配置)
     *
     * @param corpid
     * @param configAlias 通过枚举获取 比如 CompanyConfigEnum.PERFORMANCE_SET.getAlias()，CompanyConfigEnum.PERFORMANCE_TYPES.getAlias()
     * @param name
     * @param configValue 配置默认值，比如“移动端设置个人业绩目标权限”默认启用、“目标配置”默认启用全部指标
     * @return
     * @author chuanpeng.zhang
     */
    @Override
    public CompanyConfigEntity initConfigEntity(String corpid, String configAlias, String name, String configValue) throws XbbException {
        Map<String, Object> param = new HashMap<>(3);
        param.put("corpid", corpid);
        param.put("del", 0);
        param.put("configAlias", configAlias);

        List<CompanyConfigEntity> list = companyConfigModel.findEntitys(param);
        if (list.size() > 0) {
            // 数据库有该条配置，则获取
            return list.get(0);
        } else {
            // 如果数据库还没有，说明该公司还未设置，则插入一条默认配置
            CompanyConfigEntity configEntity = new CompanyConfigEntity(corpid, name, configAlias, configValue);
            companyConfigModel.insert(configEntity);
            return configEntity;
        }
    }

    /**
     * 开启关闭单个指标设置
     *
     * @param reportTargetEnableDTO
     * @return
     */
    @Override
    public BaseVO enableReportTarget(ReportTargetEnableDTO reportTargetEnableDTO) throws XbbException {
        BaseVO baseVO = new BaseVO();
        try {
            Integer code = reportTargetEnableDTO.getCode();
            Integer enable = reportTargetEnableDTO.getEnable();
            ReportTargetEnum reportTargetEnum = ReportTargetEnum.getByCode(code);
            if (code == 0 || reportTargetEnum == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SaleReportErrorCodeEnum.API_ERROR_211002.getMsg());
            }

            String codeStr = SEPARATOR + code + SEPARATOR;
            //从配置表获取
            CompanyConfigEntity config = companyConfigModel.getConfigEntity(reportTargetEnableDTO.getCorpid(), CompanyConfigEnum.REPORT_TARGETSET.getAlias());
            if (config == null) {
                //未设置则默认启用所有指标
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SaleReportErrorCodeEnum.API_ERROR_211003.getMsg());
            }

            String configValue = config.getConfigValue();
            //关闭
            if (enable == 0) {
                //要关闭的指标，没开启，无需再关闭
                if (!configValue.contains(codeStr)) {
                    return baseVO;
                }
                configValue = configValue.replace(codeStr, SEPARATOR);
                //关闭的时候要判断已经开启了几个（至少要开启一个指标）
                if (configValue.length() == 1 && Objects.equals(configValue, SEPARATOR)) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SaleReportErrorCodeEnum.API_ERROR_211004.getMsg());
                }
            } else {
                //要开启的指标，已经开启，无需再开启
                if (configValue.contains(codeStr)) {
                    return baseVO;
                }

                configValue += code + SEPARATOR;
            }
            config.setConfigValue(configValue);
            companyConfigModel.update(config);
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("启用/关闭指标设置失败", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return baseVO;
    }

    @Override
    public CompanyConfigAddBatchVO saveBatch(CompanyConfigAddBatchDTO userConfigAddBatchDTO) throws XbbException {
        CompanyConfigAddBatchVO userConfigAddBatchVO = new CompanyConfigAddBatchVO();
        try {
            Map<String, Object> params = BeanUtil.convertBean2Map(userConfigAddBatchDTO, true);
            List<String> configAliasList = new ArrayList<>();
            List<CompanyConfigEntity> resultList = new ArrayList<>();
            userConfigAddBatchDTO.getUserConfigList().forEach((item) -> {
                CompanyConfigEntity userConfigEntity = new CompanyConfigEntity();
                BeanUtil.copyProperties(item, userConfigEntity);
                userConfigEntity.setCorpid(userConfigAddBatchDTO.getCorpid());
                resultList.add(userConfigEntity);
                configAliasList.add(item.getConfigAlias());
            });
            params.put("configAliasIn", configAliasList);
            params.put("start", 0);
            params.put("pageNum", configAliasList.size());
            params.put("del", DelEnum.NORMAL.getDel());
            List<CompanyConfigEntity> userConfigList = companyConfigModel.findEntitys(params);
            if (Objects.isNull(userConfigList)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
            }
            CompanyConfigSaveBatchDTO companyConfigSaveBatchDTO = new CompanyConfigSaveBatchDTO();
            BeanUtil.copyProperties(userConfigAddBatchDTO, companyConfigSaveBatchDTO);
            companyConfigSaveBatchDTO.setUserConfigList(userConfigList);
            companyConfigSaveBatchDTO.setResultList(resultList);
            companyConfigSaveBatchDTO.setConfigAliasList(configAliasList);
            insertOrUpdate(companyConfigSaveBatchDTO);
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("UserConfigService.saveBatch批量保存数据库出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return userConfigAddBatchVO;
    }

    @Override
    public Integer getAmountPrecision(String corpid) {
        Integer decimalPrecision = AttrDecimalPrecisionHelper.DEFAULT_PRECISION;
        CompanyConfigEntity companyConfigEntity = companyConfigModel.getByConfigAlias(CompanyConfigEnum.AMOUNT_PRECISION.getAlias(), corpid);
        if (Objects.isNull(companyConfigEntity)) {
            return decimalPrecision;
        }
        String configValue = companyConfigEntity.getConfigValue();
        Integer precisionInt = StringUtil.toInt(configValue,decimalPrecision);
        return precisionInt;
    }

    @Override
    public Integer getNumberPrecision(String corpid) {

        // 默认精度值
        int decimalPrecision = AttrDecimalPrecisionHelper.DEFAULT_PRECISION;
        CompanyConfigEntity companyConfigEntity = companyConfigModel.getByConfigAlias(CompanyConfigEnum.NUMBER_PRECISION.getAlias(), corpid);
        if (Objects.isNull(companyConfigEntity)) {
            return decimalPrecision;
        }
        String configValue = companyConfigEntity.getConfigValue();
        Integer precisionInt = StringUtil.toInt(configValue,decimalPrecision);
        return precisionInt;
    }

    @Override
    public Integer getOutstockSalePrice(String corpid) {
        Integer enable = 0;
        CompanyConfigEntity companyConfigEntity = companyConfigModel.getByConfigAlias(CompanyConfigEnum.OUTSTOCK_SALE_PRICE.getAlias(), corpid);
        if (Objects.isNull(companyConfigEntity)) {
            return enable;
        }
        return StringUtil.toInt(companyConfigEntity.getConfigValue(), 0);
    }

    @Override
    public Boolean getOverOutstock(String corpid) {
        CompanyConfigEntity companyConfigEntity = companyConfigModel.getByConfigAlias(CompanyConfigEnum.CONTRACT_OUTSTOCK_OVER_SET.getAlias(), corpid);
        if (Objects.isNull(companyConfigEntity)) {
            return false;
        }
        Boolean enable = StringUtil.toInt(companyConfigEntity.getConfigValue(), 1) == 1;
        return enable;
    }

    @Override
    public Boolean getMultiUnit(String corpid) {
        CompanyConfigEntity companyConfigEntity = companyConfigModel.getByConfigAlias(CompanyConfigEnum.ENABLE_MULTI_UNIT.getAlias(), corpid);
        if (Objects.isNull(companyConfigEntity)) {
            return false;
        }
        return StringUtil.toInt(companyConfigEntity.getConfigValue(), 1) == 1;
    }

    @Override
    public Boolean getPurchaseProductConfig(String corpid) {
        CompanyConfigEntity companyConfigEntity = companyConfigModel.getByConfigAlias(CompanyConfigEnum.PURCHASE_PRODUCT_RELATE.getAlias(), corpid);
        if (Objects.isNull(companyConfigEntity)) {
            return false;
        }
        Boolean enable = StringUtil.toInt(companyConfigEntity.getConfigValue(), 1) == 1;
        return enable;
    }

    public void insertOrUpdate(CompanyConfigSaveBatchDTO companyConfigSaveBatchDTO) throws XbbException {
        try {
            List<CompanyConfigEntity> userConfigList = companyConfigSaveBatchDTO.getUserConfigList();
            List<CompanyConfigEntity> resultList = companyConfigSaveBatchDTO.getResultList();
            List<String> configAliasList = companyConfigSaveBatchDTO.getConfigAliasList();
            String corpid = companyConfigSaveBatchDTO.getCorpid();
            String userId = companyConfigSaveBatchDTO.getUserId();
            String userName = companyConfigSaveBatchDTO.getLoginUserName();
            List<CompanyConfigEntity> insertUserConfigList = new ArrayList<>();
            List<CompanyConfigEntity> updateUserConfigList = new ArrayList<>();
            Map<String, CompanyConfigEntity> userConfigMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            if (userConfigList != null && !userConfigList.isEmpty()) {
                userConfigList.forEach((item) -> {
                    userConfigMap.put(item.getConfigAlias(), item);
                });
            }
            if (userConfigList == null || userConfigList.isEmpty()) {
                for (CompanyConfigEntity item : resultList) {
                    long now = DateUtil.getInt();
                    item.setAddTime(now);
                    item.setUpdateTime(now);
                    insertUserConfigList.add(item);
                }
            } else if (configAliasList.size() != userConfigList.size()) {
                for (CompanyConfigEntity item : resultList) {
                    if (userConfigMap.containsKey(item.getConfigAlias())) {
                        long now = DateUtil.getInt();
                        item.setId(userConfigMap.get(item.getConfigAlias()).getId());
                        item.setUpdateTime(now);
                        updateUserConfigList.add(item);
                    } else {
                        long now = DateUtil.getInt();
                        item.setAddTime(now);
                        item.setUpdateTime(now);
                        insertUserConfigList.add(item);
                    }
                }
            } else {
                resultList.forEach((item) -> {
                    long now = DateUtil.getInt();
                    item.setId(userConfigMap.get(item.getConfigAlias()).getId());
                    item.setUpdateTime(now);
                    updateUserConfigList.add(item);
                });
            }
            List<String> name = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            if (!insertUserConfigList.isEmpty()) {
                companyConfigModel.insertBatch(insertUserConfigList);

                // 日志
                insertUserConfigList.forEach(insertUserConfig -> name.add(insertUserConfig.getConfigName()));
                String nameStr = StringUtils.join(name, "，");
                if(insertUserConfigList.size() > 1){
                    String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_BATCH_ADD_CONFIG), userName, insertUserConfigList.size());
                    List<InfoArrPojo> infoArrPojoList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                    InfoArrPojo infoArrPojo = new InfoArrPojo();
                    infoArrPojo.setTitle(OperateModuleTypeEnum.PAAS_CONFIG.getName());
                    infoArrPojo.setContent(nameStr);
                    infoArrPojoList.add(infoArrPojo);
                    mongoLogHelp.buildLog4InfoArr(infoArrPojoList, corpid, userId, userName, OperateModuleTypeEnum.PAAS_CONFIG, OperateTypeEnum.NEW,
                            "", "", memo, companyConfigSaveBatchDTO.getHttpHeader());
                } else if (insertUserConfigList.size() == 1) {
                    String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_ADD_CONFIG), userName, name.get(0));
                    mongoLogHelp.buildLog(corpid, userId, userName, OperateModuleTypeEnum.PAAS_CONFIG, OperateTypeEnum.NEW,
                            insertUserConfigList.get(0).getId().toString(), nameStr, memo, companyConfigSaveBatchDTO.getHttpHeader());
                }
            } else {
                companyConfigModel.updateBatch(updateUserConfigList, corpid);

                // 日志
                updateUserConfigList.forEach(updateUserConfig -> name.add(updateUserConfig.getConfigName()));
                String nameStr = StringUtils.join(name, "，");
                if(insertUserConfigList.size() > 1){
                    String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_BATCH_UPDATE_CONFIG), userName, insertUserConfigList.size());
                    List<InfoArrPojo> infoArrPojoList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                    InfoArrPojo infoArrPojo = new InfoArrPojo();
                    infoArrPojo.setTitle(OperateModuleTypeEnum.PAAS_CONFIG.getName());
                    infoArrPojo.setContent(nameStr);
                    infoArrPojoList.add(infoArrPojo);
                    mongoLogHelp.buildLog4InfoArr(infoArrPojoList, corpid, userId, userName, OperateModuleTypeEnum.PAAS_CONFIG, OperateTypeEnum.EDIT,
                            "", "", memo, companyConfigSaveBatchDTO.getHttpHeader());
                } else if (insertUserConfigList.size() == 1) {
                    String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_UPDATE_CONFIG), userName, name.get(0));
                    mongoLogHelp.buildLog(corpid, userId, userName, OperateModuleTypeEnum.PAAS_CONFIG, OperateTypeEnum.EDIT,
                            insertUserConfigList.get(0).getId().toString(), nameStr, memo, companyConfigSaveBatchDTO.getHttpHeader());
                }
            }

        } catch (Exception e) {
            LOG.error("UserConfigService 数据库更新默认排序和列表显示配置出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
    }

    @Override
    public CustomerCheckSetConfigGetVO getCustomerCheckSet(BaseDTO baseDTO) throws XbbException {
        CustomerCheckSetConfigGetVO customerCheckSetConfigGetVO = new CustomerCheckSetConfigGetVO();
        String corpid = baseDTO.getCorpid();
        String alias = CompanyConfigEnum.ONLY_IN_FORM_CHECK_SET.getAlias();
        CompanyConfigEnum configEnum = CompanyConfigEnum.getByAlias(alias);
        CompanyConfigEntity companyConfigEntity;
        try {
            companyConfigEntity = companyConfigModel.getByConfigAlias(alias, corpid);
            if (companyConfigEntity == null) {
                companyConfigEntity = new CompanyConfigEntity(corpid, configEnum.getName(), alias, configEnum.getValue());
                companyConfigModel.insert(companyConfigEntity);
            }
            String enable = companyConfigEntity.getConfigValue();
            if (Objects.equals(enable, BasicConstant.IS_USE.toString())) {
                FormConfigGetVO formConfigGetVO = formConfigService.enableCustomerCheckRepeat(baseDTO);
                customerCheckSetConfigGetVO.setFormConfigList(formConfigGetVO.getFormConfig());
            } else {
                CompanyConfigHasBeenEnableBatchDTO companyConfigHasBeenEnableBatchDTO = new CompanyConfigHasBeenEnableBatchDTO();
                BeanUtil.copyProperties(baseDTO, companyConfigHasBeenEnableBatchDTO);
                List<String> aliasList = new ArrayList<>();
                aliasList.add(CompanyConfigEnum.CUSTOMER_NAME_CHECK_SET.getAlias());
                aliasList.add(CompanyConfigEnum.CUSTOMER_PHONE_CHECK_SET.getAlias());
                companyConfigHasBeenEnableBatchDTO.setAliasList(aliasList);
                CompanyConfigHasBeenEnableBatchVO companyConfigHasBeenEnableBatchVO = hasBeenEnableBatch(companyConfigHasBeenEnableBatchDTO);
                customerCheckSetConfigGetVO.setCompanyConfigList(companyConfigHasBeenEnableBatchVO.getList());
            }
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("获取公司配置失败", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        customerCheckSetConfigGetVO.setAlias(alias);
        return customerCheckSetConfigGetVO;
    }

    @Override
    public CustomerCheckRepeatRuleGetVO getCustomerCheckRepeatRule(CustomerCheckRepeatRuleGetDTO customerCheckRepeatRuleGetDTO) throws XbbException {
        CustomerCheckRepeatRuleGetVO customerCheckRepeatRuleGetVO = new CustomerCheckRepeatRuleGetVO();
        BaseDTO baseDTO = new BaseDTO();
        BeanUtil.copyProperties(customerCheckRepeatRuleGetDTO, baseDTO);
        CustomerCheckSetConfigGetVO customerCheckSet = getCustomerCheckSet(baseDTO);
        Integer customerNameRepeat = 0;
        Integer customerPhoneRepeat = 0;
        Integer ruleType = 0;
        if (Objects.isNull(customerCheckSet.getCompanyConfigList())) {
            List<FormConfigEnablePoJo> formConfigList = customerCheckSet.getFormConfigList();
            FormConfigEnablePoJo nowFormConfig = new FormConfigEnablePoJo();
            for (FormConfigEnablePoJo formConfigEnablePoJo : formConfigList) {
                if (Objects.equals(formConfigEnablePoJo.getFormId(), customerCheckRepeatRuleGetDTO.getFormId())) {
                    nowFormConfig = formConfigEnablePoJo;
                    break;
                }
            }
            List<FormConfigPoJo> configList = nowFormConfig.getConfigList();
            for (FormConfigPoJo formConfigPoJo : configList) {
                if (Objects.equals(formConfigPoJo.getConfig(), FormConfigEnum.CUSTOMER_NAME_CHECK_SET.getConfig())) {
                    customerNameRepeat = formConfigPoJo.getConfigValue();
                } else {
                    customerPhoneRepeat = formConfigPoJo.getConfigValue();
                }
            }
            ruleType = 1;
        } else {
            List<CompanyConfigEnablePojo> companyConfigList = customerCheckSet.getCompanyConfigList();
            for (CompanyConfigEnablePojo companyConfigEnablePojo : companyConfigList) {
                if (Objects.equals(companyConfigEnablePojo.getAlias(), CompanyConfigEnum.CUSTOMER_NAME_CHECK_SET.getAlias())) {
                    customerNameRepeat = companyConfigEnablePojo.getEnable();
                } else {
                    customerPhoneRepeat = companyConfigEnablePojo.getEnable();
                }
            }
            ruleType = 0;
        }
        customerCheckRepeatRuleGetVO.setCustomerNameRule(customerNameRepeat);
        customerCheckRepeatRuleGetVO.setCustomerPhoneRule(customerPhoneRepeat);
        customerCheckRepeatRuleGetVO.setRuleType(ruleType);
        return customerCheckRepeatRuleGetVO;
    }

    /**
     * 获取钉钉待办配置
     * @param baseDTO
     * @return
     * @throws
     * @author xingxing.xiao
     * @date 2019/08/02 15:29
     */
    @Override
    public CompanyConfigSetWorkrecordVO getDintalkWorkrecordConfig(BaseDTO baseDTO) throws XbbException {
        CompanyConfigSetWorkrecordVO companyConfigSetWorkrecordVO = new CompanyConfigSetWorkrecordVO();

        String corpid = baseDTO.getCorpid();
        CompanyConfigEnum configEnum = CompanyConfigEnum.DINGTALK_WORKRECORD;
        CompanyConfigEntity companyConfigEntity;
        companyConfigEntity = companyConfigModel.getByConfigAlias(configEnum.getAlias(), corpid);
        // 如果是第一次进入页面，初始化待办配置
        if (companyConfigEntity == null) {
            companyConfigEntity = insertCompanyWorkrecordConfig(corpid, 0);
        }

        BeanUtil.copyProperties(companyConfigEntity, companyConfigSetWorkrecordVO);
        String configValue = companyConfigEntity.getConfigValue();
        CompanyConfigWorkrecordValuePojo configValuePojo = JSON.parseObject(configValue, CompanyConfigWorkrecordValuePojo.class);
        companyConfigSetWorkrecordVO.setConfigValue(configValuePojo);

        return companyConfigSetWorkrecordVO;
    }

    /**
     * 同步钉钉待办开启/关闭
     * @param companyConfigSetWorkrecordDTO
     * @return
     * @throws
     * @author xingxing.xiao
     * @date 2019/08/02 15:29
     */
    @Override
    public CompanyConfigValueSetWorkrecordVO setDintalkWorkrecordConfig(CompanyConfigSetWorkrecordDTO companyConfigSetWorkrecordDTO) throws XbbException {
        CompanyConfigValueSetWorkrecordVO configValueVo = new CompanyConfigValueSetWorkrecordVO();

        String corpid = companyConfigSetWorkrecordDTO.getCorpid();
        CompanyConfigEntity companyConfigEntity;
        String dingtalkWorkrecordAlias = CompanyConfigEnum.DINGTALK_WORKRECORD.getAlias();
        if (!Objects.equals(CompanyConfigEnum.DINGTALK_WORKRECORD.getAlias(), companyConfigSetWorkrecordDTO.getConfigAlias())) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100028, SystemErrorCodeEnum.API_ERROR_100028.getMsg());
        }
        companyConfigEntity = companyConfigModel.getByConfigAlias(dingtalkWorkrecordAlias, corpid);
        if (companyConfigEntity == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100404, SystemErrorCodeEnum.API_ERROR_100404.getMsg());
        }
        String configValue = companyConfigEntity.getConfigValue();
        CompanyConfigWorkrecordValuePojo configValuePojo = JSON.parseObject(configValue, CompanyConfigWorkrecordValuePojo.class);
        configValuePojo.setEnable(companyConfigSetWorkrecordDTO.getEnable());
        configValue = JSON.toJSONString(configValuePojo);
        companyConfigEntity.setConfigValue(configValue);
        try {
            companyConfigModel.update(companyConfigEntity);
        } catch (Exception e) {
            LOG.error("更新配置表出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }

        return configValueVo;
    }

    /**
     * 创建/更新钉钉待办模板
     * processCode 无值表示创建， 有值表示更新
     *
     * (一个公司只创建一个模板，固定两个组件，提交人和提交时间)
     * @param processCode
     * @param corpid
     * @return
     * @throws
     * @author xingxing.xiao
     * @date 2019/08/02 13:49
     */
    @Override
    public String saveDingtalkProcessTemplate(String processCode, String corpid) {
        // 获取code更新form，暂定选定三个组件创建模板(因为钉钉只会展示前三个)
        String accessToken;
        String agentId;
        try {
            accessToken = authHelper.getAccessToken(corpid);
            agentId = authHelper.getAgentId(corpid, Env.DING_XBB_APP_ID);
        } catch (Exception e) {
            LOG.error("获取accessToken或agentId失败", e);
            // 获取accessToken或agentId失败，不再执行后面的操作
            return "";
        }
        if ("".equals(agentId)) {
            return "";
        }

        SaveProcess processPojo = new SaveProcess();
        SaveProcessRequest request = new SaveProcessRequest();
        request.setAgentid(Long.valueOf(agentId));
        // 防止模板名称重复，加上各自应用的appid（再加一个随机数，模板名防重复）
        request.setName(I18nMessageUtil.getMessage(I18nStringConstant.XBB_CRM) + Env.DING_XBB_APP_ID + DingtalkWorkrecordHelper.getRandomString(5));
        request.setFake_mode(true);
        // processCode 无值表示创建， 有值表示更新
        if (StringUtil.isNotEmpty(processCode)) {
            request.setProcess_code(processCode);
        }

        List<FormComponentVo> formComponentList = new ArrayList<>();
        // 组件的属性component_name 都设为文本类型
        String textComponent = DingtalkFieldTypeEnum.TEXT.getAlias();
        // 组件-内容提要
        FormComponentVo summaryComponent = new FormComponentVo();
        FormComponentPropVo summaryProps = new FormComponentPropVo();
        summaryProps.setId(textComponent + "-" + DingtalkWorkrecordHelper.getRandomString(8));
        summaryProps.setLabel(WorkrecordTemplateEnum.SUMMARY.getName());
        summaryProps.setRequired(false);
        summaryComponent.setComponent_name(textComponent);
        summaryComponent.setProps(summaryProps);
        // 组件-提交人
        FormComponentVo nameComponent = new FormComponentVo();
        FormComponentPropVo nameProps = new FormComponentPropVo();
        nameProps.setId(textComponent + "-" + DingtalkWorkrecordHelper.getRandomString(8));
        nameProps.setLabel(WorkrecordTemplateEnum.USER_NAME.getName());
        nameProps.setRequired(false);
        nameComponent.setComponent_name(textComponent);
        nameComponent.setProps(nameProps);
        // 组件-提交时间
        FormComponentVo submitTimeComponent = new FormComponentVo();
        FormComponentPropVo submitTimeProps = new FormComponentPropVo();
        submitTimeProps.setId(textComponent + "-" + DingtalkWorkrecordHelper.getRandomString(8));
        submitTimeProps.setLabel(WorkrecordTemplateEnum.SUBMITTIME.getName());
        submitTimeProps.setRequired(false);
        submitTimeComponent.setComponent_name(textComponent);
        submitTimeComponent.setProps(submitTimeProps);

        // 组件添加到表单
        formComponentList.add(summaryComponent);
        formComponentList.add(nameComponent);
        formComponentList.add(submitTimeComponent);
        request.setForm_component_list(formComponentList);
        processPojo.setSaveProcessRequest(request);

        DingtalkWorkrecordHelper.ProcessTemplateResponse templateResponse = DingtalkWorkrecordHelper.saveWorkrecordTemplate(processPojo, accessToken);
        if (Objects.nonNull(templateResponse) && Objects.equals(templateResponse.getErrcode(), 0L)) {
            // 给 processCode 赋值
            processCode = templateResponse.getResult().getProcess_code();
        } else {
            processCode = "";
        }
        return processCode;
    }

    /**
     * 同步钉钉待办通用设置
     * @param corpid
     * @param enable 是否开启同步钉钉待办 1是 0否
     * @return
     * @throws
     * @author xingxing.xiao
     * @date 2019/08/05 19:40
     */
    @Override
    public CompanyConfigEntity insertCompanyWorkrecordConfig(String corpid, Integer enable) throws XbbException {
        // 创建待办模板
        String processCode = "";
        processCode = saveDingtalkProcessTemplate(processCode, corpid);

        CompanyConfigWorkrecordValuePojo configValueObj = new CompanyConfigWorkrecordValuePojo();
        configValueObj.setEnable(enable);
        configValueObj.setBtnName(I18nMessageUtil.getMessage(I18nStringConstant.SYNC_PROCESS_APPROVALS_TO_DING));
        configValueObj.setTips(I18nMessageUtil.getMessage(I18nStringConstant.DINGTALK_WORKRECORD_TIPS));
        configValueObj.setDingtalkProcessCode(processCode);
        String configValue = JSON.toJSONString(configValueObj);

        // 生成一条钉钉待办配置保存到 tb_company_config 表
        CompanyConfigEntity companyConfigEntity = new CompanyConfigEntity(corpid, CompanyConfigEnum.DINGTALK_WORKRECORD.getName(), CompanyConfigEnum.DINGTALK_WORKRECORD.getAlias(), configValue);

        try {
            companyConfigModel.insert(companyConfigEntity);
        } catch (Exception e) {
            LOG.error("插入配置表出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return companyConfigEntity;
    }

    @Override
    public String getCompanyConfigSetValue(String corpid, String alias) throws XbbException {
        String configValue = null;
        try {
            CompanyConfigEntity companyConfigEntity = companyConfigModel.getByConfigAlias(alias, corpid);
            if (Objects.isNull(companyConfigEntity)) {
                CompanyConfigEnum companyConfigEnum = CompanyConfigEnum.getByAlias(alias);
                configValue = companyConfigEnum.getValue();
            } else {
                configValue = companyConfigEntity.getConfigValue();
            }
        } catch (Exception e) {
            LOG.error("getCompanyConfigSetValue error", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        return configValue;
    }

    @Override
    public CompanyConfigRaidersWhiteVO setRaidersWhite(CompanyConfigRaidersWhiteDTO companyConfigRaidersWhiteDTO) throws XbbException {
        if(!proBaseConfig.getXbbCode().equals(companyConfigRaidersWhiteDTO.getXbbCode())){
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006, SystemErrorCodeEnum.API_ERROR_100006.getMsg());
        }
        CompanyConfigRaidersWhiteVO companyConfigRaidersWhiteVO = new CompanyConfigRaidersWhiteVO();

        //1加入白名单 0移出白名单
        Integer operate = companyConfigRaidersWhiteDTO.getOperate();
        boolean flag = Objects.equals(operate, 1);
        String alias = CompanyConfigEnum.RAIDERS_WHITE.getAlias();
        String name = CompanyConfigEnum.RAIDERS_WHITE.getName();
        CompanyConfigEntity entity;
        String configValue = "";
        try {
            entity = companyConfigModel.getByConfigAlias(alias, RaidersConstant.RAIDERS_WHITE_CORPID);
            String whiteCorpid = companyConfigRaidersWhiteDTO.getWhiteCorpid();
            Set<String> valueSet = new HashSet<>();
            if (entity == null) {
                entity = new CompanyConfigEntity();
                entity.setCorpid("0");
                entity.setConfigName(name);
                entity.setConfigAlias(alias);
            } else {
                //把旧的白名单读取到
                List<String> valueList = JsonHelperUtil.parseArray(entity.getConfigValue(), String.class);
                valueSet.addAll(valueList);
                //加入白名单时，条件过滤：防止重复设置，最多设置10个白名单公司
                if (flag && valueSet.contains(whiteCorpid)) {
                    throw new XbbException(RaidersErrorCodeEnum.API_ERROR_800025, RaidersErrorCodeEnum.API_ERROR_800025.getMsg());
                }
                if (flag && valueSet.size() >= RaidersConstant.MAX_COUNT_RAIDERS_WHITE) {
                    throw new XbbException(RaidersErrorCodeEnum.API_ERROR_800027, String.format(RaidersErrorCodeEnum.API_ERROR_800027.getMsg(), RaidersConstant.MAX_COUNT_RAIDERS_WHITE));
                }
                if (!flag && !valueSet.contains(whiteCorpid)) {
                    //移出白名单，首先需要该公司在白名单列表内
                    throw new XbbException(RaidersErrorCodeEnum.API_ERROR_800026, RaidersErrorCodeEnum.API_ERROR_800026.getMsg());
                }
            }
            //塞入新的白名单
            if (flag) {
                valueSet.add(whiteCorpid);
            } else {
                valueSet.remove(whiteCorpid);
            }
            configValue = JSONArray.toJSONString(valueSet);
            entity.setConfigValue(configValue);
            companyConfigModel.save(entity);

            companyConfigRaidersWhiteVO.setConfigAlias(alias);
            companyConfigRaidersWhiteVO.setConfigName(name);
            companyConfigRaidersWhiteVO.setConfigValue(valueSet);
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("设置价值攻略白名单失败", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }

        // 缓存，因为该配置是所有公司公用的，因此缓存的key无需拼接corpid，且缓存时效设置比较长
        String key = alias;
        paasRedisHelper.setValue(RedisConstant.KEY_COMPANY_CONFIG, key, configValue, TimeConstant.SECONDS_PER_WEEK);
        return companyConfigRaidersWhiteVO;
    }

    @Override
    public List<String> getAiAssistantWhite() throws XbbException {

        String key = CompanyConfigEnum.AI_ASSISTANT_WHITE.getAlias();
        String configValue = paasRedisHelper.getValue(RedisConstant.KEY_COMPANY_CONFIG, key);
        if (Objects.isNull(configValue)) {
            configValue = getCompanyConfigSetValue(PaasConstant.DEFAULT_DATA_CORPID, key);
            paasRedisHelper.setValue(RedisConstant.KEY_COMPANY_CONFIG, key, configValue, TimeConstant.TEN_MINUTE_DURATION);
        }

        return JsonHelperUtil.parseArray(configValue, String.class);
    }

    @Override
    public CompanyConfigJxcConfigVO getJxcConfig(CompanyConfigGetJxcConfigDTO companyConfigGetJxcConfigDTO) throws XbbException {
        CompanyConfigHasBeenEnableBatchDTO companyConfigHasBeenEnableBatchDTO = new CompanyConfigHasBeenEnableBatchDTO();
        BeanUtil.copyProperties(companyConfigGetJxcConfigDTO, companyConfigHasBeenEnableBatchDTO);
        companyConfigHasBeenEnableBatchDTO.setAliasList(Arrays.asList(CompanyConfigEnum.ENABLE_BATCH_SHELF_MANAGEMENT.getAlias(), CompanyConfigEnum.ENABLE_SEQ_MANAGEMENT.getAlias(),CompanyConfigEnum.ENABLE_MULTI_UNIT.getAlias(),CompanyConfigEnum.ENABLE_PURCHASE_PASSAGE.getAlias(),CompanyConfigEnum.ENABLE_MINI_STOCK.getAlias()));
        CompanyConfigHasBeenEnableBatchVO companyConfigHasBeenEnableBatchVO = hasBeenEnableBatch(companyConfigHasBeenEnableBatchDTO);
        List<CompanyConfigEnablePojo> list = companyConfigHasBeenEnableBatchVO.getList();
        list.forEach(config -> {
            config.setSort(0);
            CompanyConfigEnum companyConfigEnum = CompanyConfigEnum.getByAlias(config.getAlias());
            if (Objects.nonNull(companyConfigEnum)) {
                config.setSort(companyConfigEnum.getSort());
            }
        });
        list.sort(Comparator.comparingInt(CompanyConfigEnablePojo::getSort));
        List<CompanyConfigEnableAndMemoPojo> configList = new ArrayList<>();
        CompanyConfigEnableAndMemoPojo companyConfigEnableAndMemoPojo;
        for (CompanyConfigEnablePojo companyConfigEnablePojo : list) {
            companyConfigEnableAndMemoPojo = new CompanyConfigEnableAndMemoPojo(companyConfigEnablePojo.getAlias(), companyConfigEnablePojo.getEnable(), I18nMessageUtil.getMessage(companyConfigEnablePojo.getName()));
            companyConfigEnableAndMemoPojo.setMemo(I18nMessageUtil.getMessage(Objects.requireNonNull(CompanyConfigEnum.getByAlias(companyConfigEnablePojo.getAlias())).getMemo()));
            configList.add(companyConfigEnableAndMemoPojo);
        }
        CompanyConfigJxcConfigVO companyConfigJxcConfigVO = new CompanyConfigJxcConfigVO();
        companyConfigJxcConfigVO.setList(configList);
        return companyConfigJxcConfigVO;
    }

    @Override
    public JXCSetListVO getJxcConfigList(CompanyConfigGetJxcConfigDTO companyConfigGetJxcConfigDTO) throws XbbException {
        JXCSetListVO jxcSetListVO = new JXCSetListVO();
        try {
            List<FundSetMenuPojo> list = new ArrayList<>();
            for (JxcSetEnum value : JxcSetEnum.values()) {
                FundSetMenuPojo fundSetMenuPojo = new FundSetMenuPojo(value.getType(), value.getName());
                list.add(fundSetMenuPojo);
            }
            jxcSetListVO.setList(list);
        } catch (Exception e) {
            LOG.error("获取进销存设置菜单失败");
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return jxcSetListVO;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public CompanyConfigEnableVO enableJxcConfig(CompanyConfigEnableDTO companyConfigEnableDTO) throws XbbException {
        CompanyConfigEnableVO companyConfigEnableVO = new CompanyConfigEnableVO();
        String corpid = companyConfigEnableDTO.getCorpid();
        String userId = companyConfigEnableDTO.getUserId();
        // 登录用户名
        String loginUserName = companyConfigEnableDTO.getLoginUserName();
        String alias = companyConfigEnableDTO.getAlias();
        String enable = companyConfigEnableDTO.getValue();

        // 过滤不正确的值
        enable = BasicConstant.IS_USE.toString().equals(enable) ? enable : BasicConstant.NO_USE.toString();
        CompanyConfigEnum configEnum = CompanyConfigEnum.getByAlias(alias);
        if (configEnum == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100088);
        }
        CompanyConfigEntity companyConfigEntity = companyConfigModel.getByConfigAlias(alias, corpid);
        if (Objects.equals(configEnum, CompanyConfigEnum.ENABLE_STOCK_FLOW_BILL)) {
            if (BasicConstant.IS_USE.toString().equals(enable)) {
                // 本地调试用
                // paasRedisHelper.removeValue(RedisPrefixConstant.ENABLE_STOCK_FLOW_BILL, corpid);
                JSONObject jsonObject = JsonHelperUtil.parseObject(paasRedisHelper.getValue(RedisPrefixConstant.ENABLE_STOCK_FLOW_BILL, corpid));
                Long endTime = DateTimeUtil.getWeekLastDayInSomeday(DateTimeUtil.getTodayInt());
                if (jsonObject.isEmpty()) {
                    jsonObject.put(BusinessConstant.NUMBER_OF_TIMES, 1);
                    jsonObject.put(BusinessConstant.TIME_LIMIT, endTime);
                } else {
                    Integer times = jsonObject.getInteger(BusinessConstant.NUMBER_OF_TIMES);
                    Long limitTime = jsonObject.getLong(BusinessConstant.TIME_LIMIT);
                    Long now = DateTimeUtil.getInt();
                    if (limitTime >= now) {
                        if (times > 1) {
                            throw new XbbException(ProductErrorCodeEnum.API_ERROR_205068);
                        } else {
                            jsonObject.put(BusinessConstant.NUMBER_OF_TIMES, times + 1);
                        }
                    } else {
                        jsonObject.put(BusinessConstant.NUMBER_OF_TIMES, 1);
                        jsonObject.put(BusinessConstant.TIME_LIMIT, endTime);
                    }
                }
                paasRedisHelper.setValue(RedisPrefixConstant.ENABLE_STOCK_FLOW_BILL, corpid, jsonObject, RedisConstant.HUGE_DURATION);
            }
        }
        // 有开启批次保质期或序列号管理的产品不允许关闭
        if (Objects.equals(configEnum, CompanyConfigEnum.ENABLE_BATCH_SHELF_MANAGEMENT) || Objects.equals(configEnum, CompanyConfigEnum.ENABLE_SEQ_MANAGEMENT)) {
            List<Integer> businessTypeList;
            if (Objects.equals(configEnum, CompanyConfigEnum.ENABLE_BATCH_SHELF_MANAGEMENT)) {
                if (Objects.equals(enable, BasicConstant.NO_USE.toString()) && productService.hasBatchOrSeqProduct(configEnum, corpid)) {
                    throw new XbbException(ProductErrorCodeEnum.API_ERROR_205072);
                }
                businessTypeList = ProductConstant.HAS_BATCH_PRODUCT;
            } else {
                if (Objects.equals(enable, BasicConstant.NO_USE.toString()) && productService.hasBatchOrSeqProduct(configEnum, corpid)) {
                    throw new XbbException(ProductErrorCodeEnum.API_ERROR_205073);
                }
                businessTypeList  = Collections.singletonList(XbbRefTypeEnum.PRODUCT.getCode());
            }
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put(ParameterConstant.CORPID, corpid);
            param.put("businessTypeList", businessTypeList);
            param.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
            List<PaasFormExplainEntity> listForUpdateProduct = paasFormExplainModel.getNoHandleExplainsByFindEntitys(param);
            Map<Integer, List<PaasFormExplainEntity>> map = new HashMap<>(listForUpdateProduct.size());
            listForUpdateProduct.forEach(explain -> {
                List<PaasFormExplainEntity> explainList = map.getOrDefault(explain.getBusinessType(), new ArrayList<>());
                if (!Objects.equals(explain.getExplains(), "[]")) {
                    explainList.add(explain);
                    map.put(explain.getBusinessType(), explainList);
                }
            });
            for (Map.Entry<Integer, List<PaasFormExplainEntity>> entry : map.entrySet()) {
                for (PaasFormExplainEntity paasFormExplainEntity : entry.getValue()) {
                    List<FieldAttrEntity> fieldAttrEntities = JSONArray.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
                    autoRegisterHandleSpecialBusinessFactory.getSpecialBusiness(BusinessTypeToServiceEnum.getByBusinessType(entry.getKey())).formatBatchOrSeqExplain(fieldAttrEntities, enable, alias);
                    // explain太大，批量更新较循环更新无优势
                    paasFormExplainEntity.setExplains(JSON.toJSONString(fieldAttrEntities));
                    paasFormExplainModel.update(paasFormExplainEntity);
                }
            }
        }
        // 多单位不需要加菜单
        if (Objects.equals(configEnum, CompanyConfigEnum.ENABLE_MULTI_UNIT)) {
            PaasFormExplainEntity paasFormExplainEntity = paasFormExplainModel.getByBusinessType(XbbRefTypeEnum.PRODUCT.getCode(), corpid);
            List<FieldAttrEntity> fieldAttrEntities = JSONArray.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
            boolean isShow = BasicConstant.IS_USE.toString().equals(enable);
            fieldAttrEntities.forEach(item -> {
                if (Objects.equals(ProductEnum.ENABLE_MULTI_UNIT.getAttr(), item.getAttr())) {
                    item.setEditHide(isShow? 0 : 1);
                    item.setVisible(isShow? 1 : 0);
                }
            });
            if (!isShow) {
                SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
                BoolQueryBuilder boolQueryBuilder = boolQuery();
                boolQueryBuilder.filter(termQuery("corpid.keyword",corpid));
                boolQueryBuilder.filter(termQuery(ParameterConstant.DEL,DelEnum.NORMAL.getDel()));
                boolQueryBuilder.filter(termQuery(ProductEnum.getEsAttr4Keyword(ProductEnum.PARENT_ID), 0));
                boolQueryBuilder.filter(termQuery(ProductEnum.getEsAttr4Keyword(ProductEnum.ENABLE_MULTI_UNIT), 1));
                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_PRODUCT.getType()));
                sourceBuilder.query(boolQueryBuilder);
                //分页
                PageRequest pageRequest = EsUtil.setPage(sourceBuilder, 1, 1);
                SearchRequest searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_PRODUCT.getIndex());
                searchRequest.source(sourceBuilder);
                XbbAggregatedPage<PaasFormDataEntityExt> esEntities = xbbElasticsearchRestTemplate.queryForPages(pageRequest, searchRequest, PaasFormDataEntityExt.class);
                if (esEntities.getTotalElements() > 0) {
                    throw new XbbException(ProductErrorCodeEnum.API_ERROR_205095);
                }
            }
            paasFormExplainEntity.setExplains(JSON.toJSONString(fieldAttrEntities));
            paasFormExplainModel.update(paasFormExplainEntity);
            // 待系列公司级配置也不需要加菜单
        } else if (!(Objects.equals(configEnum, CompanyConfigEnum.ENABLE_MINI_STOCK) || Objects.equals(configEnum, CompanyConfigEnum.ENABLE_PURCHASE_PASSAGE))){
            AccordConfigMenuPojo accordConfigMenuPojo = new AccordConfigMenuPojo();
            BeanUtil.copyProperties(companyConfigEnableDTO, accordConfigMenuPojo);
            accordConfigMenuPojo.setConfigEntity(companyConfigEntity);
            accordConfigMenuPojo.setConfigValue(enable);
            accordConfigMenuPojo.setConfigEnum(configEnum);
            initJxcMenuHelp.addAccordConfigMenu(accordConfigMenuPojo);
        }
        // 保险起见，不管什么操作都先删除之前的流水
        if (Objects.equals(configEnum, CompanyConfigEnum.ENABLE_STOCK_FLOW_BILL)) {
            FlowBillInsertDTO flowBillInsertDTO = new FlowBillInsertDTO();
            stockFlowBillModel.deleteAllByCorpId(corpid);
            stockSurplusRecordModel.deleteAllByCorpId(corpid);
            if (BasicConstant.IS_USE.toString().equals(enable)) {
                BeanUtil.copyProperties(companyConfigEnableDTO, flowBillInsertDTO);
                stockFlowBillService.insertMonthBeforeStockFlow(flowBillInsertDTO);
            }
            batchFlowBillModel.deleteAllByCorpId(corpid);
            batchSurplusRecordModel.deleteAllByCorpId(corpid);
            if (BasicConstant.IS_USE.toString().equals(enable)) {
                batchFlowBillService.insertMonthBeforeBatchFlow(flowBillInsertDTO);
            }
        }
        try {
            if (companyConfigEntity == null) {
                companyConfigEntity = new CompanyConfigEntity(corpid, configEnum.getName(), alias, enable);
                companyConfigModel.insert(companyConfigEntity);
            } else {
                companyConfigEntity.setConfigValue(enable);
                companyConfigModel.update(companyConfigEntity);
            }
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("启用/关闭公司配置失败", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        // 缓存
        String key = corpid + StringConstant.COLON + alias;
        paasRedisHelper.setValue(RedisConstant.KEY_COMPANY_CONFIG, key, enable,
                TimeConstant.SECONDS_EIGHT_HOUR);

        // 日志
        String memo;
        OperateTypeEnum operateTypeEnum;
        if (Objects.equals(BasicConstant.IS_USE.toString(), enable)) {
            operateTypeEnum = OperateTypeEnum.ENABLE;
            memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_OPEN_COMPANY_CONFIG), loginUserName,  I18nMessageUtil.getMessage(configEnum.getName()));
        } else {
            operateTypeEnum = OperateTypeEnum.CLOSE;
            memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_CLOSE_COMPANY_CONFIG), loginUserName, I18nMessageUtil.getMessage(configEnum.getName()));
        }
        mongoLogHelp.buildLog(corpid, userId, loginUserName, OperateModuleTypeEnum.COMPANY_CONFIG, operateTypeEnum, companyConfigEntity.getId().toString(), OperateModuleTypeEnum.COMPANY_CONFIG.getName(), memo, companyConfigEnableDTO.getHttpHeader());

        return companyConfigEnableVO;
    }



    @Override
    public ScriptVO setBlacklistBigDataCorpList(BlacklistBigDataCorpDTO blacklistBigDataCorpDTO) throws XbbException {
        try {
            Set<String> blacklistBigDataCorpSet = new HashSet<>();
            List<String> blacklistBigDataCorp = blacklistBigDataCorpDTO.getBlacklistBigDataCorp();
            //缓存前缀or companyConfig表内configAlias
            String configAlias = CompanyConfigEnum.BLACKLIST_BIG_DATA_CORP.getAlias();
            String key = StringConstant.DEFAULT_CORPID;
            CompanyConfigEntity companyConfigEntity = companyConfigModel.getByConfigAlias(configAlias, key);
            if (Objects.isNull(companyConfigEntity) && !Objects.equals(BasicConstant.ZERO, blacklistBigDataCorpDTO.getAdd())) {
                blacklistBigDataCorpSet.addAll(blacklistBigDataCorp);
            } else {
                List<String> list = JsonHelperUtil.parseArray(companyConfigEntity.getConfigValue(), String.class);
                if (Objects.equals(BasicConstant.ZERO, blacklistBigDataCorpDTO.getAdd())) {
                    //0删除
                    list.removeAll(blacklistBigDataCorp);
                } else {
                    //其他默认为添加
                    list.addAll(blacklistBigDataCorp);
                }
                blacklistBigDataCorpSet.addAll(list);
            }
            companyConfigModel.save(key, configAlias, CompanyConfigEnum.BLACKLIST_BIG_DATA_CORP.getName(), JSON.toJSONString(blacklistBigDataCorpSet));
            paasRedisHelper.setValue(configAlias, key, JSON.toJSONString(blacklistBigDataCorpSet), RedisTimeConstant.TEN_MINUTES);
        } catch (Exception e) {
            LOG.error("companyConfigService.setBlacklistBigDataCorpList 设置黑名单出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        ScriptVO scriptVO = new ScriptVO();
        scriptVO.setMsg("success");
        return scriptVO;
    }

    @Override
    public Integer aliyunCallcentersave(CompanyConfigAddDTO companyConfigAddDTO) throws XbbException {
        if (Objects.isNull(companyConfigAddDTO.getConfigName()) || Objects.isNull(companyConfigAddDTO.getConfigAlias())) {
            companyConfigAddDTO.setConfigName(CompanyConfigEnum.ALIYUN_CALLCENTER_CONFIGURATION.getName());
            companyConfigAddDTO.setConfigAlias(CompanyConfigEnum.ALIYUN_CALLCENTER_CONFIGURATION.getAlias());
        }
        // 根据配置別名获取单行数据
        CompanyConfigEntity companyConfigEntity = companyConfigModel.getByConfigAlias(companyConfigAddDTO.getConfigAlias(), companyConfigAddDTO.getCorpid());
        Integer save = 0;
        // 如果查询不到就是添加
        if(companyConfigEntity == null){
            CompanyConfigEntity entity = new CompanyConfigEntity();
            BeanUtils.copyProperties(companyConfigAddDTO, entity);
            entity.setDel(0);
            save = companyConfigModel.insert(entity);
        } else {
            // 新配置
            JSONObject newConfig = JSONObject.parseObject(companyConfigAddDTO.getConfigValue());
            // 老配置
            JSONObject oldConfig = JSONObject.parseObject(companyConfigEntity.getConfigValue());
            newConfig.forEach(oldConfig::put);
            companyConfigEntity.setConfigValue(oldConfig.toString());
            save = companyConfigModel.update(companyConfigEntity);
        }
        return save;
    }

    @Override
    public CompanyConfigFindVO findCompanyConfig(CompanyConfigFindDTO findDTO) throws XbbException {
        CompanyConfigEntity companyConfigEntity = companyConfigModel.getByConfigAlias(findDTO.getConfigAlias(), findDTO.getCorpid());
        CompanyConfigFindVO findVO = new CompanyConfigFindVO();
        if (Objects.nonNull(companyConfigEntity)) {
            BeanUtils.copyProperties(companyConfigEntity, findVO);
        }
        return findVO;
    }

    @Override
    public CompanyConfigFindVO findCompanyConfigByRedis(CompanyConfigFindDTO findDTO) {
        String key = findDTO.getCorpid() + StringConstant.COLON + findDTO.getConfigAlias();
        String value = paasRedisHelper.getValue(RedisConstant.KEY_COMPANY_CONFIG, key);
        CompanyConfigFindVO findVO = new CompanyConfigFindVO();
        if (Objects.isNull(value)) {
            CompanyConfigEntity companyConfigEntity = companyConfigModel.getByConfigAlias(findDTO.getConfigAlias(), findDTO.getCorpid());
            if (Objects.nonNull(companyConfigEntity)) {
                findVO.setConfigValue(companyConfigEntity.getConfigValue());
                paasRedisHelper.setValue(RedisConstant.KEY_COMPANY_CONFIG, key, companyConfigEntity.getConfigValue(), TimeConstant.SECONDS_PER_DAY);
            }
        } else {
            findVO.setConfigValue(value);
        }
        return findVO;
    }

    @Override
    public long getDwTriggerTime() throws XbbException {
        String key = CompanyConfigEnum.DW_TRIGGER_TIME.getAlias();
        String configValue = paasRedisHelper.getValue(RedisConstant.KEY_COMPANY_CONFIG, key);
        if (Objects.isNull(configValue)) {
            configValue = getCompanyConfigSetValue(PaasConstant.DEFAULT_DATA_CORPID, key);
            paasRedisHelper.setValue(RedisConstant.KEY_COMPANY_CONFIG, key, configValue, TimeConstant.SECONDS_TWO_HOUR);
        }

        return Long.parseLong(configValue);
    }

    @Override
    public CompanyConfigGetPerformanceLeaveVO getPerformanceLeave(CompanyConfigGetPerformanceLeaveDTO companyConfigGetPerformanceLeaveDTO) throws XbbException {
        CompanyConfigGetPerformanceLeaveVO companyConfigGetPerformanceLeaveVO = new CompanyConfigGetPerformanceLeaveVO();
        String corpid = companyConfigGetPerformanceLeaveDTO.getCorpid();
        String alias = CompanyConfigEnum.PERFORMANCE_LEAVE.getAlias();
        try {
            boolean isShow = commonHelp.isShowPerformLeave(corpid);
            companyConfigGetPerformanceLeaveVO.setAlias(alias);
            companyConfigGetPerformanceLeaveVO.setPerformanceLeaveMarks(isShow ? "1" : "0");
        } catch (Exception e) {
            LOG.error("获取绩效目标离职员工配置失败", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return companyConfigGetPerformanceLeaveVO;
    }
}
